home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / xnot12a.zip / BASIC.C < prev    next >
C/C++ Source or Header  |  1993-05-20  |  10KB  |  489 lines

  1. #include "jam.h"
  2. #include "stdlib.h"
  3. #include "def.h"
  4. #include "keyname.h"
  5.  
  6. /*
  7.  *        Basic cursor motion commands.
  8.  *
  9.  * The routines in this file are the basic
  10.  * command functions for moving the cursor around on
  11.  * the screen, setting mark, and swapping dot with
  12.  * mark. Only moves between lines, which might make the
  13.  * current buffer framing bad, are hard.
  14.  */
  15.  
  16. static char *eobmsg = "End of buffer.";
  17. static char *bobmsg = "Begining of buffer.";
  18.  
  19. /*
  20.  * Go to beginning of line.
  21.  */
  22. /*ARGSUSED*/
  23. gotobol(f, n)
  24. int f, n;
  25. {
  26.     curwp->w_doto  = 0;
  27.     return (TRUE);
  28. }
  29.  
  30. /*
  31.  * Move cursor backwards. Do the
  32.  * right thing if the count is less than
  33.  * 0. Error if you try to move back from
  34.  * the beginning of the buffer.
  35.  */
  36. /*ARGSUSED*/
  37. backchar(f, n)
  38. register int f, n;
  39. {
  40.     register LINE    *lp;
  41.  
  42.     if (n < 0) 
  43.       return forwchar(f, -n);
  44.     while (n--) {
  45.         if (curwp->w_doto == 0) {
  46.             if ((lp=lback(curwp->w_dotp)) == curbp->b_linep) {
  47.                 if (!(f & FFRAND))
  48.                     ewprintf("Beginning of buffer");
  49.                 return (FALSE);
  50.             }
  51.             curwp->w_dotp  = lp;
  52.             curwp->w_doto  = llength(lp);
  53.             curwp->w_flag |= WFMOVE;
  54.         } else
  55.             curwp->w_doto--;
  56.     }
  57.     return TRUE;
  58. }
  59.  
  60. /*
  61.  * Go to end of line.
  62.  */
  63. /*ARGSUSED*/
  64. gotoeol(f, n)
  65. int f, n;
  66. {
  67.     curwp->w_doto  = llength(curwp->w_dotp);
  68.     return (TRUE);
  69. }
  70.  
  71. /*
  72.  * Move cursor forwards. Do the
  73.  * right thing if the count is less than
  74.  * 0. Error if you try to move forward
  75.  * from the end of the buffer.
  76.  */
  77. /*ARGSUSED*/
  78. forwchar(f, n)
  79. register int f, n;
  80. {
  81.     if (n < 0) return backchar(f, -n);
  82.     while (n--) {
  83.         if (curwp->w_doto == llength(curwp->w_dotp)) {
  84.             curwp->w_dotp  = lforw(curwp->w_dotp);
  85.             if (curwp->w_dotp == curbp->b_linep) {
  86.                 curwp->w_dotp = lback(curwp->w_dotp);
  87.                 if (!(f & FFRAND))
  88.                     ewprintf(eobmsg);
  89.                 return FALSE;
  90.             }
  91.             curwp->w_doto  = 0;
  92.             curwp->w_flag |= WFMOVE;
  93.         } else
  94.             curwp->w_doto++;
  95.     }
  96.     return TRUE;
  97. }
  98.  
  99. /*
  100.  * Go to the beginning of the
  101.  * buffer. Setting WFHARD is conservative,
  102.  * but almost always the case.
  103.  */
  104. gotobob(f, n)
  105. int f, n;
  106. {
  107.     (VOID) setmark(f, n) ;
  108.     curwp->w_dotp  = lforw(curbp->b_linep);
  109.     curwp->w_doto  = 0;
  110.     curwp->w_flag |= WFHARD;
  111.     return TRUE;
  112. }
  113.  
  114. /*
  115.  * Go to the end of the buffer.
  116.  * Setting WFHARD is conservative, but
  117.  * almost always the case.
  118.  */
  119. gotoeob(f, n)
  120. int f, n;
  121. {
  122.     (VOID) setmark(f, n) ;
  123.     curwp->w_dotp  = lback(curbp->b_linep);
  124.     curwp->w_doto  = llength(curwp->w_dotp);
  125.     curwp->w_flag |= WFHARD;
  126.     return TRUE;
  127. }
  128.  
  129. /*
  130.  * Move forward by full lines.
  131.  * If the number of lines to move is less
  132.  * than zero, call the backward line function to
  133.  * actually do it. The last command controls how
  134.  * the goal column is set.
  135.  */
  136. /*ARGSUSED*/
  137. forwline(f, n)
  138. int f, n;
  139. {
  140.     register LINE    *dlp;
  141.  
  142.     if (n < 0)
  143.         return backline(f|FFRAND, -n);
  144.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  145.         setgoal();
  146.     thisflag |= CFCPCN;
  147.     if (n == 0) 
  148.       return TRUE;
  149.     dlp = curwp->w_dotp;
  150.     while (dlp!=curbp->b_linep && n--)
  151.         dlp = lforw(dlp);
  152.     curwp->w_flag |= WFMOVE;
  153.     if(dlp==curbp->b_linep) 
  154.       {         /* ^N at end of buffer creates lines (like gnu) */
  155.           if (curbp->b_flag & BFVIEW)
  156.             {
  157.               /* don't beep on special buffer (hack check!)
  158.               */
  159.               if (curbp->b_modes[0] != name_mode(BlistStr))
  160.                 ttbeep();
  161.               return TRUE;
  162.         }
  163.       if(!(curbp->b_flag&BFCHG)) 
  164.             {    /* first change */
  165.         curbp->b_flag |= BFCHG;
  166.         curbp->b_flag |= BFINC;
  167.         curwp->w_flag |= WFMODE;
  168.         }
  169.       curwp->w_doto = 0;
  170.       while(n-- >= 0) {
  171.         if((dlp = lallocx(0)) == NULL) 
  172.             return FALSE;
  173.         dlp->l_fp = curbp->b_linep;
  174.         dlp->l_bp = lback(dlp->l_fp);
  175.         dlp->l_bp->l_fp = dlp->l_fp->l_bp = dlp;
  176.         }
  177.         curwp->w_dotp = lback(curbp->b_linep);
  178.     } else {
  179.         curwp->w_dotp  = dlp;
  180.         curwp->w_doto  = getgoal(dlp);
  181.     }
  182.     return TRUE;
  183. }
  184.  
  185. /*
  186.  * This function is like "forwline", but
  187.  * goes backwards. The scheme is exactly the same.
  188.  * Check for arguments that are less than zero and
  189.  * call your alternate. Figure out the new line and
  190.  * call "movedot" to perform the motion.
  191.  */
  192. /*ARGSUSED*/
  193. backline(f, n)
  194. int f, n;
  195. {
  196.     register LINE    *dlp;
  197.  
  198.     if (n < 0) return forwline(f|FFRAND, -n);
  199.     if ((lastflag&CFCPCN) == 0)        /* Fix goal.        */
  200.         setgoal();
  201.     thisflag |= CFCPCN;
  202.     dlp = curwp->w_dotp;
  203.     while (n-- && lback(dlp)!=curbp->b_linep)
  204.         dlp = lback(dlp);
  205.     curwp->w_dotp  = dlp;
  206.     curwp->w_doto  = getgoal(dlp);
  207.     curwp->w_flag |= WFMOVE;
  208.     return TRUE;
  209. }
  210.  
  211. /*
  212.  * Set the current goal column,
  213.  * which is saved in the external variable "curgoal",
  214.  * to the current cursor column. The column is never off
  215.  * the edge of the screen; it's more like display then
  216.  * show position.
  217.  */
  218. VOID setgoal() 
  219. {
  220.     curgoal = getcolpos() - 1;        /* Get the position.    */
  221.     /* we can now display past end of display, don't chop! */
  222. }
  223.  
  224. /*
  225.  * This routine looks at a line (pointed
  226.  * to by the LINE pointer "dlp") and the current
  227.  * vertical motion goal column (set by the "setgoal"
  228.  * routine above) and returns the best offset to use
  229.  * when a vertical motion is made into the line.
  230.  */
  231. getgoal(dlp) 
  232. register LINE *dlp; 
  233. {
  234.     register int    c;
  235.     register int    col;
  236.     register int    newcol;
  237.     register int    dbo;
  238.  
  239.     col = 0;
  240.     dbo = 0;
  241.     while (dbo != llength(dlp)) {
  242.         c = lgetc(dlp, dbo);
  243.         newcol = col;
  244.         if (c == '\t')
  245.             newcol |= 0x07;
  246.         else if (ISCTRL(c) != FALSE)
  247.             ++newcol;
  248.         ++newcol;
  249.         if (newcol > curgoal)
  250.             break;
  251.         col = newcol;
  252.         ++dbo;
  253.     }
  254.     return (dbo);
  255. }
  256.  
  257. /*
  258.  * Scroll forward by a specified number
  259.  * of lines, or by a full page if no argument.
  260.  * The "2" is the window overlap (this is the default
  261.  * value from ITS EMACS). Because the top line in
  262.  * the window is zapped, we have to do a hard
  263.  * update and get it back.
  264.  */
  265. /*ARGSUSED*/
  266. forwpage(f, n)
  267. register int f, n;
  268. {
  269.     register LINE    *lp;
  270.  
  271.     if (!(f & FFARG)) {
  272.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  273.         if (n <= 0)            /* Forget the overlap    */
  274.             n = 1;            /* if tiny window.    */
  275.     } else if (n < 0)
  276.         return backpage(f|FFRAND, -n);
  277. #ifdef    CVMVAS
  278.     else                    /* Convert from pages    */
  279.         n *= curwp->w_ntrows;        /* to lines.        */
  280. #endif
  281.     lp = curwp->w_linep;
  282.         if (lforw(lp) == curbp->b_linep)
  283.           ewprintf(eobmsg);
  284.     while (n-- && lforw(lp)!=curbp->b_linep)
  285.       lp = lforw(lp);
  286.     curwp->w_linep = lp;
  287.     curwp->w_flag |= WFHARD;
  288.  
  289.     /* if in current window, don't move dot 
  290.         */
  291.     for(n = curwp->w_ntrows; n-- && lp!=curbp->b_linep; lp = lforw(lp))
  292.       if(lp==curwp->w_dotp) 
  293.             return TRUE;
  294.     curwp->w_dotp  = curwp->w_linep;
  295.     curwp->w_doto  = 0;
  296.     return TRUE;
  297. }
  298.  
  299. /*
  300.  * This command is like "forwpage",
  301.  * but it goes backwards. The "2", like above,
  302.  * is the overlap between the two windows. The
  303.  * value is from the ITS EMACS manual. The
  304.  * hard update is done because the top line in
  305.  * the window is zapped.
  306.  */
  307. /*ARGSUSED*/
  308. backpage(f, n)
  309. register int f, n;
  310. {
  311.     register LINE    *lp;
  312.  
  313.     if (!(f & FFARG)) {
  314.         n = curwp->w_ntrows - 2;    /* Default scroll.    */
  315.         if (n <= 0)            /* Don't blow up if the */
  316.             n = 1;            /* window is tiny.    */
  317.     } else if (n < 0)
  318.         return forwpage(f|FFRAND, -n);
  319. #ifdef    CVMVAS
  320.     else                    /* Convert from pages    */
  321.         n *= curwp->w_ntrows;        /* to lines.        */
  322. #endif
  323.     lp = curwp->w_linep;
  324.         if (lback(lp) == curbp->b_linep)
  325.           ewprintf(bobmsg);
  326.     while (n-- && lback(lp)!=curbp->b_linep)
  327.         lp = lback(lp);
  328.     curwp->w_linep = lp;
  329.     curwp->w_flag |= WFHARD;
  330.     /* if in current window, don't move dot */
  331.     for(n = curwp->w_ntrows; n-- && lp!=curbp->b_linep; lp = lforw(lp))
  332.         if(lp==curwp->w_dotp) return TRUE;
  333.     curwp->w_dotp = curwp->w_linep;
  334.     curwp->w_doto = 0;
  335.     return TRUE;
  336. }
  337.  
  338. /* These functions are provided for compatibility with Gosling's Emacs.
  339.  *    They are used to scroll the display up (or down) one line at a time.
  340.  */
  341.  
  342. #ifdef GOSMACS
  343. forw1page(f, n)
  344. int f, n;
  345. {
  346.     if (!(f & FFARG))  {
  347.             n = 1;
  348.         f = FFUNIV;
  349.     }
  350.     return (forwpage(f|FFRAND, n));
  351. }
  352.  
  353. back1page(f, n)
  354. int f, n;
  355. {
  356.     if (!(f & FFARG)) {
  357.             n = 1;
  358.         f = FFUNIV;
  359.     }
  360.     return(backpage(f|FFRAND, n));
  361. }
  362. #endif
  363.  
  364. /*
  365.  * Page the other window. Check to make sure it exists, then
  366.  * nextwind, forwpage and restore window pointers.
  367.  */
  368. pagenext(f, n)
  369. int f, n;
  370. {
  371.     register EWINDOW *wp;
  372.  
  373.     if (wheadp->w_wndp == NULL) {
  374.         ewprintf("No other window");
  375.         return FALSE;
  376.     }
  377.     wp = curwp;
  378.     (VOID) nextwind(f, n);
  379.     (VOID) forwpage(f, n);
  380.     curwp = wp;
  381.     curbp = wp->w_bufp;
  382.     return TRUE;
  383. }
  384.  
  385. /*
  386.  * Internal set mark routine, used by other functions (daveb).
  387.  */
  388. VOID isetmark()
  389. {
  390.     curwp->w_markp = curwp->w_dotp;
  391.     curwp->w_marko = curwp->w_doto;
  392. }
  393.  
  394. /*
  395.  * Set the mark in the current window
  396.  * to the value of dot. A message is written to
  397.  * the echo line.  (ewprintf knows about macros)
  398.  */
  399. /*ARGSUSED*/
  400. setmark(f, n)
  401. int f, n;
  402. {
  403.     isetmark();
  404.     ewprintf(Markset);
  405.     return TRUE;
  406. }
  407.  
  408. /*
  409.  * Swap the values of "dot" and "mark" in
  410.  * the current window. This is pretty easy, because
  411.  * all of the hard work gets done by the standard routine
  412.  * that moves the mark about. The only possible
  413.  * error is "no mark".
  414.  */
  415. /*ARGSUSED*/
  416. swapmark(f, n)
  417. int f, n;
  418. {
  419.     register LINE    *odotp;
  420.     register int    odoto;
  421.  
  422.     if (curwp->w_markp == NULL) {
  423.         ewprintf("No mark in this window");
  424.         return FALSE;
  425.     }
  426.     odotp = curwp->w_dotp;
  427.     odoto = curwp->w_doto;
  428.     curwp->w_dotp  = curwp->w_markp;
  429.     curwp->w_doto  = curwp->w_marko;
  430.     curwp->w_markp = odotp;
  431.     curwp->w_marko = odoto;
  432.     curwp->w_flag |= WFMOVE;
  433.     return TRUE;
  434. }
  435.  
  436. /*
  437.  * Go to a specific line, mostly for
  438.  * looking up errors in C programs, which give the
  439.  * error a line number. If an argument is present, then
  440.  * it is the line number, else prompt for a line number
  441.  * to use.
  442.  */
  443. /*ARGSUSED*/
  444. gotoline(f, n)
  445. register int f, n;
  446. {
  447.   register int    s;
  448.   char buf[32];
  449.  
  450.   if (!(f & FFARG)) {
  451.     if ((s=ereply("Goto line: ", buf, sizeof(buf))) != TRUE)
  452.       return s;
  453.     n = atoi(buf);
  454.     }
  455.  
  456.   return(gotobigline((RSIZE)n));
  457. }
  458.  
  459. /* split from gotoline to handle much bigger numbers
  460. */
  461. int gotobigline(n)
  462. RSIZE n;
  463. {
  464.   register LINE    *clp;
  465.  
  466.   if (n > 0) {
  467.     clp = lforw(curbp->b_linep);    /* "clp" is first line    */
  468.     while (--n > 0) {
  469.       if (lforw(clp) == curbp->b_linep) 
  470.         break;
  471.       clp = lforw(clp);
  472.       }
  473.     } 
  474.   else {
  475.     clp = lback(curbp->b_linep);    /* clp is last line */
  476.     while (n < 0) {
  477.     if (lback(clp) == curbp->b_linep) 
  478.       break;
  479.     clp = lback(clp);
  480.     n++;
  481.     }
  482.   }
  483.  
  484.   curwp->w_dotp = clp;
  485.   curwp->w_doto = 0;
  486.   curwp->w_flag |= WFMOVE;
  487.   return TRUE;
  488. }
  489.